using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Metrics;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Volo.Abp.DependencyInjection;

namespace Matrix.Configuration.Telemetry
{
    /// <summary>
    /// Matrix Configuration自定义业务指标
    /// 提供配置管理相关的关键业务指标监控
    /// </summary>
    public class MatrixConfigurationMetrics : ITransientDependency
    {
        private readonly Counter<long> _configurationReadCounter;
        private readonly Counter<long> _configurationWriteCounter;
        private readonly Histogram<double> _configurationReadDuration;
        private readonly Histogram<double> _configurationWriteDuration;
        private readonly UpDownCounter<long> _activeConfigurationsGauge;
        private readonly Counter<long> _cacheHitCounter;
        private readonly Counter<long> _cacheMissCounter;
        private readonly Histogram<double> _databaseQueryDuration;
        private readonly Counter<long> _databaseConnectionCounter;
        private readonly Counter<long> _configurationValidationErrors;
        private readonly Counter<long> _backgroundJobExecuted;
        private readonly Histogram<double> _backgroundJobDuration;

        // 缓存相关指标
        private readonly Counter<long> _cacheSetCounter;
        private readonly Counter<long> _cacheDeleteCounter;
        private readonly Histogram<double> _cacheOperationDuration;

        // 批量操作指标
        private readonly Counter<long> _batchOperationCounter;
        private readonly Histogram<double> _batchOperationDuration;
        private readonly Histogram<double> _batchSizeHistogram;

        private readonly ILogger<MatrixConfigurationMetrics> _logger;

        public MatrixConfigurationMetrics(IMeterFactory meterFactory, ILogger<MatrixConfigurationMetrics> logger)
        {
            _logger = logger;
            var meter = meterFactory.Create("Matrix.Configuration");

            // 配置读写指标
            _configurationReadCounter = meter.CreateCounter<long>(
                "configuration.reads.total",
                description: "配置读取总数");

            _configurationWriteCounter = meter.CreateCounter<long>(
                "configuration.writes.total",
                description: "配置写入总数");

            _configurationReadDuration = meter.CreateHistogram<double>(
                "configuration.read.duration",
                unit: "ms",
                description: "配置读取耗时");

            _configurationWriteDuration = meter.CreateHistogram<double>(
                "configuration.write.duration",
                unit: "ms",
                description: "配置写入耗时");

            _activeConfigurationsGauge = meter.CreateUpDownCounter<long>(
                "configuration.active.count",
                description: "活跃配置项数量");

            _configurationValidationErrors = meter.CreateCounter<long>(
                "configuration.validation.errors.total",
                description: "配置验证错误总数");

            // 缓存指标
            var cacheMeter = meterFactory.Create("Matrix.Configuration.Cache");
            _cacheHitCounter = cacheMeter.CreateCounter<long>(
                "cache.hits.total",
                description: "缓存命中次数");

            _cacheMissCounter = cacheMeter.CreateCounter<long>(
                "cache.misses.total",
                description: "缓存未命中次数");

            _cacheSetCounter = cacheMeter.CreateCounter<long>(
                "cache.sets.total",
                description: "缓存设置次数");

            _cacheDeleteCounter = cacheMeter.CreateCounter<long>(
                "cache.deletes.total",
                description: "缓存删除次数");

            _cacheOperationDuration = cacheMeter.CreateHistogram<double>(
                "cache.operation.duration",
                unit: "ms",
                description: "缓存操作耗时");

            // 数据库指标
            var dbMeter = meterFactory.Create("Matrix.Configuration.Database");
            _databaseQueryDuration = dbMeter.CreateHistogram<double>(
                "database.query.duration",
                unit: "ms",
                description: "数据库查询耗时");

            _databaseConnectionCounter = dbMeter.CreateCounter<long>(
                "database.connections.total",
                description: "数据库连接总数");

            // 后台作业指标
            var jobMeter = meterFactory.Create("Matrix.Configuration.Jobs");
            _backgroundJobExecuted = jobMeter.CreateCounter<long>(
                "background.jobs.executed.total",
                description: "后台作业执行总数");

            _backgroundJobDuration = jobMeter.CreateHistogram<double>(
                "background.jobs.duration",
                unit: "ms",
                description: "后台作业执行耗时");

            // 批量操作指标
            var batchMeter = meterFactory.Create("Matrix.Configuration.Batch");
            _batchOperationCounter = batchMeter.CreateCounter<long>(
                "batch.operations.total",
                description: "批量操作总数");

            _batchOperationDuration = batchMeter.CreateHistogram<double>(
                "batch.operation.duration",
                unit: "ms",
                description: "批量操作耗时");

            _batchSizeHistogram = batchMeter.CreateHistogram<double>(
                "batch.operation.size",
                description: "批量操作大小");

            _logger.LogInformation("Matrix Configuration指标已初始化完成");
        }

        #region 配置读写指标

        /// <summary>
        /// 记录配置读取指标
        /// </summary>
        public void RecordConfigurationRead(string operation, TimeSpan duration, bool success = true, string? namespace = null, string? errorType = null)
        {
            var tags = new List<KeyValuePair<string, object>>
            {
                new("operation", operation),
                new("status", success ? "success" : "error")
            };

            if (!string.IsNullOrEmpty(namespace))
                tags.Add(new("configuration.namespace", namespace));

            if (!success && !string.IsNullOrEmpty(errorType))
                tags.Add(new("error.type", errorType));

            _configurationReadCounter.Add(1, tags.ToArray());
            _configurationReadDuration.Record(duration.TotalMilliseconds, tags.ToArray());

            _logger.LogDebug("记录配置读取指标: {Operation} - {Duration}ms - {Status}",
                operation, duration.TotalMilliseconds, success ? "成功" : "失败");
        }

        /// <summary>
        /// 记录配置写入指标
        /// </summary>
        public void RecordConfigurationWrite(string operation, TimeSpan duration, bool success = true, string? namespace = null, string? errorType = null)
        {
            var tags = new List<KeyValuePair<string, object>>
            {
                new("operation", operation),
                new("status", success ? "success" : "error")
            };

            if (!string.IsNullOrEmpty(namespace))
                tags.Add(new("configuration.namespace", namespace));

            if (!success && !string.IsNullOrEmpty(errorType))
                tags.Add(new("error.type", errorType));

            _configurationWriteCounter.Add(1, tags.ToArray());
            _configurationWriteDuration.Record(duration.TotalMilliseconds, tags.ToArray());

            _logger.LogDebug("记录配置写入指标: {Operation} - {Duration}ms - {Status}",
                operation, duration.TotalMilliseconds, success ? "成功" : "失败");
        }

        /// <summary>
        /// 更新活跃配置数量
        /// </summary>
        public void UpdateActiveConfigurations(long count)
        {
            try
            {
                // 获取当前值并计算差值
                var currentTags = new List<KeyValuePair<string, object>>();
                var currentValue = _activeConfigurationsGauge.GetCurrentObservableValue().Count;
                var delta = count - currentValue;

                _activeConfigurationsGauge.Add(delta, currentTags.ToArray());

                _logger.LogDebug("更新活跃配置数量: {Count} (变化: {Delta})", count, delta);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "更新活跃配置数量时发生错误");
            }
        }

        /// <summary>
        /// 记录配置验证错误
        /// </summary>
        public void RecordConfigurationValidationError(string validationType, string? namespace = null)
        {
            var tags = new List<KeyValuePair<string, object>>
            {
                new("validation.type", validationType)
            };

            if (!string.IsNullOrEmpty(namespace))
                tags.Add(new("configuration.namespace", namespace));

            _configurationValidationErrors.Add(1, tags.ToArray());

            _logger.LogWarning("记录配置验证错误: {ValidationType} - 命名空间: {Namespace}", validationType, namespace);
        }

        #endregion

        #region 缓存指标

        /// <summary>
        /// 记录缓存命中
        /// </summary>
        public void RecordCacheHit(string cacheLevel, string? operation = null)
        {
            var tags = new List<KeyValuePair<string, object>>
            {
                new("level", cacheLevel)
            };

            if (!string.IsNullOrEmpty(operation))
                tags.Add(new("operation", operation));

            _cacheHitCounter.Add(1, tags.ToArray());

            _logger.LogDebug("记录缓存命中: {CacheLevel} - {Operation}", cacheLevel, operation);
        }

        /// <summary>
        /// 记录缓存未命中
        /// </summary>
        public void RecordCacheMiss(string cacheLevel, string? operation = null)
        {
            var tags = new List<KeyValuePair<string, object>>
            {
                new("level", cacheLevel)
            };

            if (!string.IsNullOrEmpty(operation))
                tags.Add(new("operation", operation));

            _cacheMissCounter.Add(1, tags.ToArray());

            _logger.LogDebug("记录缓存未命中: {CacheLevel} - {Operation}", cacheLevel, operation);
        }

        /// <summary>
        /// 记录缓存设置操作
        /// </summary>
        public void RecordCacheSet(string operation, TimeSpan duration, bool success = true)
        {
            var tags = new List<KeyValuePair<string, object>>
            {
                new("operation", operation),
                new("status", success ? "success" : "error")
            };

            _cacheSetCounter.Add(1, tags.ToArray());
            _cacheOperationDuration.Record(duration.TotalMilliseconds, tags.ToArray());

            _logger.LogDebug("记录缓存设置操作: {Operation} - {Duration}ms - {Status}",
                operation, duration.TotalMilliseconds, success ? "成功" : "失败");
        }

        /// <summary>
        /// 记录缓存删除操作
        /// </summary>
        public void RecordCacheDelete(string operation, TimeSpan duration, bool success = true)
        {
            var tags = new List<KeyValuePair<string, object>>
            {
                new("operation", operation),
                new("status", success ? "success" : "error")
            };

            _cacheDeleteCounter.Add(1, tags.ToArray());
            _cacheOperationDuration.Record(duration.TotalMilliseconds, tags.ToArray());

            _logger.LogDebug("记录缓存删除操作: {Operation} - {Duration}ms - {Status}",
                operation, duration.TotalMilliseconds, success ? "成功" : "失败");
        }

        #endregion

        #region 数据库指标

        /// <summary>
        /// 记录数据库查询耗时
        /// </summary>
        public void RecordDatabaseQuery(string operation, TimeSpan duration, bool success = true, string? errorType = null)
        {
            var tags = new List<KeyValuePair<string, object>>
            {
                new("operation", operation),
                new("status", success ? "success" : "error")
            };

            if (!success && !string.IsNullOrEmpty(errorType))
                tags.Add(new("error.type", errorType));

            _databaseQueryDuration.Record(duration.TotalMilliseconds, tags.ToArray());

            _logger.LogDebug("记录数据库查询: {Operation} - {Duration}ms - {Status}",
                operation, duration.TotalMilliseconds, success ? "成功" : "失败");
        }

        /// <summary>
        /// 记录数据库连接
        /// </summary>
        public void RecordDatabaseConnection(string operation, bool success = true)
        {
            var tags = new List<KeyValuePair<string, object>>
            {
                new("operation", operation),
                new("status", success ? "success" : "error")
            };

            _databaseConnectionCounter.Add(1, tags.ToArray());

            _logger.LogDebug("记录数据库连接: {Operation} - {Status}", operation, success ? "成功" : "失败");
        }

        #endregion

        #region 后台作业指标

        /// <summary>
        /// 记录后台作业执行
        /// </summary>
        public void RecordBackgroundJob(string jobType, TimeSpan duration, bool success = true, string? errorType = null)
        {
            var tags = new List<KeyValuePair<string, object>>
            {
                new("job.type", jobType),
                new("status", success ? "success" : "error")
            };

            if (!success && !string.IsNullOrEmpty(errorType))
                tags.Add(new("error.type", errorType));

            _backgroundJobExecuted.Add(1, tags.ToArray());
            _backgroundJobDuration.Record(duration.TotalMilliseconds, tags.ToArray());

            _logger.LogDebug("记录后台作业: {JobType} - {Duration}ms - {Status}",
                jobType, duration.TotalMilliseconds, success ? "成功" : "失败");
        }

        #endregion

        #region 批量操作指标

        /// <summary>
        /// 记录批量操作
        /// </summary>
        public void RecordBatchOperation(string operation, int batchSize, TimeSpan duration, bool success = true, string? errorType = null)
        {
            var tags = new List<KeyValuePair<string, object>>
            {
                new("operation", operation),
                new("status", success ? "success" : "error")
            };

            if (!success && !string.IsNullOrEmpty(errorType))
                tags.Add(new("error.type", errorType));

            _batchOperationCounter.Add(1, tags.ToArray());
            _batchOperationDuration.Record(duration.TotalMilliseconds, tags.ToArray());
            _batchSizeHistogram.Record(batchSize, tags.ToArray());

            _logger.LogDebug("记录批量操作: {Operation} - 批量大小: {BatchSize} - {Duration}ms - {Status}",
                operation, batchSize, duration.TotalMilliseconds, success ? "成功" : "失败");
        }

        #endregion
    }

    /// <summary>
    /// 扩展方法，用于Activity追踪增强
    /// </summary>
    public static class ActivityExtensions
    {
        private static readonly ActivitySource ActivitySource = new("Matrix.Configuration");

        /// <summary>
        /// 开始配置操作追踪
        /// </summary>
        public static Activity? StartConfigurationOperation(string operationName, string? @namespace = null, string? name = null)
        {
            var tags = new ActivityTagsCollection();

            if (!string.IsNullOrEmpty(@namespace))
                tags.Add("configuration.namespace", @namespace);

            if (!string.IsNullOrEmpty(name))
                tags.Add("configuration.name", name);

            var activity = ActivitySource.StartActivity(
                $"configuration.{operationName}",
                ActivityKind.Server,
                tags: tags);

            if (activity != null)
            {
                activity.SetTag("operation.type", operationName);
            }

            return activity;
        }

        /// <summary>
        /// 添加异常信息到活动
        /// </summary>
        public static void AddException(this Activity? activity, Exception exception)
        {
            if (activity == null) return;

            activity.SetStatus(ActivityStatusCode.Error, exception.Message);
            activity.AddTag("error.type", exception.GetType().Name);
            activity.AddTag("error.message", exception.Message);
            activity.AddEvent(new ActivityEvent("exception", tags: new ActivityTagsCollection
            {
                ["exception.type"] = exception.GetType().Name,
                ["exception.message"] = exception.Message,
                ["exception.stacktrace"] = exception.StackTrace ?? ""
            }));
        }

        /// <summary>
        /// 添加业务上下文到活动
        /// </summary>
        public static void AddBusinessContext(this Activity? activity, string key, object value)
        {
            activity?.AddTag($"business.{key}", value.ToString());
        }

        /// <summary>
        /// 添加性能指标到活动
        /// </summary>
        public static void AddPerformanceMetrics(this Activity? activity, TimeSpan duration)
        {
            if (activity == null) return;

            activity.SetTag("duration.ms", duration.TotalMilliseconds);
            activity.SetTag("performance.slow", duration.TotalMilliseconds > 1000);
        }
    }
}